home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / MACSHELL / MS1 / COMMANDS / DIFF.C < prev    next >
Text File  |  1992-12-02  |  9KB  |  368 lines

  1. /*
  2.  *    MacShell Source File
  3.  *
  4.  *    Copyright (c) 1989, 1990, 1991, 1992  Suick Bay Technologies.  All rights reserved.
  5.  *
  6.  *
  7.  *    RESTRICTIONS ON MacShell program and source code.
  8.  *
  9.  *    Ñ╩MacShell¬ is a product of Suick Bay Technologies and is provided for
  10.  *    restricted use by the owner of the CDROM "Disk to the future II".
  11.  *
  12.  *    Ñ╩No permission is granted for any commercial use without the written
  13.  *    consent of the Suick Bay Technologies.
  14.  *
  15.  *    Ñ╩No permission is granted for any redistribution of any kind use without
  16.  *    the written consent of the Suick Bay Technologies.
  17.  *
  18.  *    Ñ╩Permission is granted to use this for any personal noncommercial use.
  19.  *
  20.  *    Ñ╩You may not distribute source or executable code at all, nor may you 
  21.  *    distribute it with or within a commercial product without the written
  22.  *    consent of the Suick Bay Technologies.  Please send modifications to 
  23.  *    the author for inclusion in updates to the program.  Thanks.
  24.  *
  25.  *
  26.  *    MacShell¬ IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  27.  *    WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  28.  *    PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  29.  *
  30.  *    SUICK BAY TECHNOLOGIES SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  31.  *    INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY MACSHELL
  32.  *    OR ANY PART THEREOF. 
  33.  *
  34.  *    In no event will Suick Bay Technologies be liable for any lost revenue
  35.  *    or profits or other special, indirect and consequential damages, even if
  36.  *    Suick Bay Technologies has been advised of the possibility of such damages.
  37.  *
  38.  *    Suick Bay Technologies can be reached at:
  39.  *    
  40.  *    8768 Cottonwood lane
  41.  *    Maple Grove, MN 55369
  42.  *    Voice: (612) 425-7025
  43.  *    AppleLink: D5233
  44.  *    
  45.  *
  46.  *    No parts of this software may be reproduced or stored in a
  47.  *    retrieval system or transmitted in any form, or any means,
  48.  *    electronic, mechanical, photocopying, recording or otherwise,
  49.  *    without the prior written permission of Suick Bay Technologies.
  50.  *    
  51.  *    Spread the word and not the disk.
  52.  *    
  53.  *    SPK 012290    :    Initial
  54.  */
  55.  
  56. #include    "SystemPub.h"
  57. #include    "Proc.h"
  58. #include    "ShellPub.h"
  59. #include    "path.h"
  60.  
  61. #define        BUFSIZE        256L
  62.  
  63. #define        _DIFFDEBUG
  64.  
  65. /*******************************************************************
  66.  *
  67.  *    Function DIFF
  68.  *
  69.  *
  70.  *    diff [options] file1 file2
  71.  *
  72.  *    options
  73.  *        -h        do a fast half-hearted job.
  74.  *        -b         trailing blanks are ignored.
  75.  *
  76.  *******************************************************************/
  77.  
  78. #define        diffFast    (**MyShell).Proc[ProcID].bflags.f0
  79. #define        diffBlank    (**MyShell).Proc[ProcID].bflags.f1
  80. #define        diffAbort    (**MyShell).Proc[ProcID].bflags.f2
  81.  
  82. #define        misLineCnt    (**MyShell).Proc[ProcID].int0
  83.  
  84.  
  85. int16    StrDiff( char *s1, char *s2, Boolean fast )
  86. {
  87.     if( fast )
  88.         return( strcmp( s1, s2 ) );
  89.     
  90. #ifdef    DIFFDEBUG
  91.     printf( "StrDiff \n:%s:%s", s1, s2 );
  92. #endif
  93.  
  94.     while( *s1 )
  95.         {
  96.         /* remove white space from line */
  97.         
  98.         while( *s1 && isShellSpace( *s1 ) )
  99.             s1++;
  100.         
  101.         while( *s2 && isShellSpace( *s2 ) )
  102.             s2++;
  103.         
  104.         while( *s1 && (*s1 == *s2 ) && !isShellSpace( *s1 ) )
  105.             {
  106.             s1++;
  107.             s2++;
  108.             }
  109.         
  110.         if( *s1 )
  111.             {
  112.             if( isShellSpace( *s1 ) && isShellSpace( *s2 ) )
  113.                 ;
  114.             else             /* error */
  115.                 return( 1 );
  116.             }
  117.         else if( *s2 )        /* error */
  118.             return( 1 );
  119.         else
  120.             return( 0 );    /* ok */
  121.         }
  122. }
  123.  
  124. /*******************************************************************/
  125.  
  126. Boolean    SyncToLine( char *line, int16 fileRefNum, int16 syncCnt,
  127.             int32 *syncPos, Boolean fast )
  128. {
  129. char    buf[ BUFSIZE ];
  130. OSErr    err;
  131.  
  132. #ifdef    DIFFDEBUG
  133.     printf( "SyncToLine ref %d %s", fileRefNum, line );
  134. #endif
  135.  
  136.     while( syncCnt-- )
  137.         {
  138.         err = GetFPos( fileRefNum, syncPos );
  139.         err = ReadLine( fileRefNum, buf, BUFSIZE );
  140.         if( err )
  141.             break;
  142.             
  143.         if( StrDiff( line, buf, fast ) == 0 )    /* in sync */
  144.             return( TRUE );
  145.         }
  146.         
  147.     return( FALSE );
  148. }
  149.  
  150. /*******************************************************************/
  151.  
  152. void    ListDiffTo( WHandle ShellWh, int16 ProcID, char indicator,
  153.              int16 fileRefNum, int32 syncPos, int16 *lineNum )
  154. {
  155. int32    fPos;
  156. char    buf[ BUFSIZE ];
  157. OSErr    err;
  158.  
  159.     err = GetFPos( fileRefNum, &fPos );
  160.  
  161. #ifdef    DIFFDEBUG
  162.     printf( "ListDiffTo ref %d from %ld to %ld\n", fileRefNum, fPos, syncPos );
  163. #endif
  164.  
  165.     while( fPos < syncPos )
  166.         {
  167.         err = ReadLine( fileRefNum, buf, BUFSIZE );
  168.         procPrintf( ShellWh, ProcID, "%2d %c %s", *lineNum, indicator, buf );
  169.         
  170.         if( err )
  171.             break;
  172.  
  173.         err = GetFPos( fileRefNum, &fPos );
  174.         (*lineNum)++;
  175.         }
  176. }
  177.  
  178. /*******************************************************************/
  179.  
  180. void    DIFFFile( WHandle ShellWh, int16 ProcID, char *file1, char *file2 )
  181. {
  182. int16    aRefNum,     bRefNum,
  183.         aErr,         bErr,
  184.         aLineNum,    bLineNum,
  185.         filesSame = TRUE,
  186.         cantDiff = TRUE;
  187. char    aBuf[ BUFSIZE ],
  188.         bBuf[ BUFSIZE ];
  189. int32    aPos, bPos, syncPos;
  190. ShellWindRec    **MyShell = (ShellWindRec **) (**ShellWh).thing;
  191.  
  192.     aRefNum = OpenFileDirect( file1, 'TEXT', fsRdPerm );
  193.     
  194.     if( aRefNum )
  195.         {
  196.         bRefNum = OpenFileDirect( file2, 'TEXT', fsRdPerm );
  197.         
  198.         if( bRefNum )
  199.             {
  200.             aLineNum = 1;
  201.             bLineNum = 1;
  202.             cantDiff = FALSE;
  203.             
  204.             while( filesSame && !diffAbort )
  205.                 {
  206.                 if( UserAbort() )
  207.                     diffAbort = TRUE;
  208.                     
  209.                 aErr = GetFPos( aRefNum, &aPos );
  210.                 bErr = GetFPos( bRefNum, &bPos );
  211.                 
  212.                 aErr = ReadLine( aRefNum, aBuf, BUFSIZE );
  213.                 bErr = ReadLine( bRefNum, bBuf, BUFSIZE );
  214.                 
  215.                 if( aErr || bErr )
  216.                     break;
  217.                 else    /* compare differences */
  218.                     {
  219.                     if( StrDiff( aBuf, bBuf, diffFast ) )        /* lines are different */
  220.                         {
  221.                         if( SyncToLine( aBuf, bRefNum, misLineCnt, &syncPos, diffFast ) )
  222.                             {
  223.                             SetFPos( bRefNum, fsFromStart, bPos );
  224.                             procPrintf( ShellWh, ProcID, "add at line %d\n", aLineNum );
  225.                             ListDiffTo( ShellWh, ProcID, '>', bRefNum, syncPos, &bLineNum );
  226.                             bErr = ReadLine( bRefNum, bBuf, BUFSIZE );
  227.                             }
  228.                         else
  229.                             {
  230.                             SetFPos( bRefNum, fsFromStart, bPos );
  231.                             if( SyncToLine( bBuf, aRefNum, misLineCnt, &syncPos, diffFast  ) )
  232.                                 {
  233.                                 SetFPos( aRefNum, fsFromStart, aPos );
  234.                                 procPrintf( ShellWh, ProcID, "add at line %d\n", bLineNum );
  235.                                 ListDiffTo( ShellWh, ProcID, '<', aRefNum, syncPos, &aLineNum );
  236.                                 }
  237.                             else
  238.                                 {
  239.                                 procPrintf( ShellWh, ProcID, "change\n" );
  240.                                 
  241.                                 SetFPos( aRefNum, fsFromStart, aPos );
  242.                                 SetFPos( bRefNum, fsFromStart, bPos );
  243.                                 aErr = ReadLine( aRefNum, aBuf, BUFSIZE );
  244.                                 bErr = ReadLine( bRefNum, bBuf, BUFSIZE );
  245.                                  
  246.                                 procPrintf( ShellWh, ProcID, "%2d > %s%2d < %s",
  247.                                     aLineNum, aBuf, bLineNum, bBuf );
  248.                                 }
  249.                             }
  250.                         }
  251.                     }
  252.                 aLineNum++;
  253.                 bLineNum++;
  254.                 }
  255.             
  256.             FSClose( aRefNum );
  257.             FSClose( bRefNum );
  258.             }
  259.         else
  260.             {
  261.             FSClose( aRefNum );
  262.             procPrintf( ShellWh, ProcID, "diff : can't open %s\n", file2 );
  263.             }
  264.         }
  265.     else
  266.         procPrintf( ShellWh, ProcID, "diff : can't open %s\n", file1 );
  267.  
  268.         
  269.     if( cantDiff )
  270.         procPrintf( ShellWh, ProcID, "diff : can't compare %s and %s\n",
  271.             file1, file2 );
  272.  
  273.     ResetShellPWD( ShellWh );
  274. }
  275.  
  276. /*******************************************************************/
  277.  
  278. Boolean        DoDIFF( int16 ProcToken, WHandle ShellWh, int16 ProcID, char *string )
  279. {
  280. int16            i, argc;
  281. char            *cp, arg1[ 256 ], arg2[ 256 ];
  282. ShellWindRec    **MyShell = (ShellWindRec **) (**ShellWh).thing;
  283.  
  284.     switch( ProcToken )
  285.         {
  286.         case    PROC_INIT    :
  287.             (**MyShell).Proc[ ProcID ].flags = TRUE;
  288.             break;
  289.             
  290.         case    PROC_TERM    :
  291.         case    PROC_BREAK    :
  292.             diffAbort = TRUE;
  293.             /* Tell the shell that we're done */
  294.             SendOutToken( ShellWh, ProcID, PROC_BREAK );
  295.             /* Turn ourself off */
  296.             (**MyShell).Proc[ ProcID ].ProcActive = FALSE;
  297.             break;
  298.             
  299.         case    PROC_STDIN    :
  300.             if( (**MyShell).Proc[ ProcID ].flags )
  301.                 {
  302.                 (**MyShell).Proc[ ProcID ].flags = FALSE;        
  303.  
  304.                 diffFast = FALSE;
  305.                 diffBlank = FALSE;
  306.                 diffAbort = FALSE;
  307.                 misLineCnt = 16;
  308.                 
  309.                 /* get arguments */
  310.                 argc = (**MyShell).Proc[ ProcID ].argc;
  311.                 for( i = 1; i < argc; i++ )
  312.                     {
  313.                     GetArgv( ShellWh, ProcID, i, arg1 );
  314.                     cp = arg1;
  315.         
  316.                     if( *cp++ == '-' )
  317.                         while( *cp )
  318.                             switch( *cp++ )
  319.                                 {
  320.                                 case    'h'    :    /* fast half-hearted job */
  321.                                     diffFast = TRUE;
  322.                                     misLineCnt = 4;
  323.                                     break;
  324.                                     
  325.                                 case    'b'    :    /* trailing blanks are ignored */
  326.                                     diffBlank = TRUE;
  327.                                     break;
  328.                                     
  329.                                 case    's'    :    /* resync count */
  330.                                     break;
  331.                                 }
  332.                     }
  333.  
  334.                 *arg1 = '\0';
  335.                 *arg2 = '\0';
  336.                 
  337.                 for( i = 1; i < (**MyShell).Proc[ ProcID ].argc; i++ )
  338.                     {
  339.                     if( *arg1 == '\0' )
  340.                         {
  341.                         GetArgv( ShellWh, ProcID, i, arg1 );
  342.                         if( *arg1 == '-' )
  343.                             *arg1 = '\0';
  344.                         }
  345.                     else if( *arg2 == '\0' )
  346.                         {
  347.                         GetArgv( ShellWh, ProcID, i, arg2 );
  348.                         if( *arg2== '-' )
  349.                             *arg2 = '\0';
  350.                         else
  351.                             break;
  352.                         }
  353.                     }
  354.                     
  355.                 if( *arg1 && *arg2 )
  356.                     DIFFFile( ShellWh, ProcID, arg1, arg2 );
  357.  
  358.                 /* Tell the shell that we're done */
  359.                 SendOutToken(  ShellWh, ProcID, PROC_BREAK );
  360.                 
  361.                 /* Turn ourself off */
  362.                 (**MyShell).Proc[ ProcID ].ProcActive = FALSE;
  363.                 return( FALSE );
  364.                 }
  365.         }
  366. }
  367.  
  368.